package com.muqi.server.controller;

import cn.hutool.core.util.StrUtil;
import com.muqi.server.common.annotated.RequiresPermission;
import com.muqi.server.common.auth.DoubleToken;
import com.muqi.server.common.response.ResponseClass;
import com.muqi.server.common.utilis.UserUtil;
import com.muqi.server.domain.bo.UserBO;
import com.muqi.server.domain.dto.LoginDTO;
import com.muqi.server.domain.dto.RegisterDTO;
import com.muqi.server.domain.vo.LoginVO;
import com.muqi.server.domain.vo.UserInfoVO;
import com.muqi.server.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@CrossOrigin(origins = "*",allowedHeaders = "*", maxAge = 3600)
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;


    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginDTO loginDTO) {
        Integer userId = userService.login(loginDTO);
        if (userId == null || userId == -1) { // 如果 userId 为 null 或 -1，则表示登录失败
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseClass(HttpStatus.BAD_REQUEST.value(), null,"登录失败，用户名或密码错误"));
        }

        UserBO userBO = userService.getUserById(userId);
        LoginVO loginVo = new LoginVO();
        loginVo.setNickname(userBO.getNickname());
        loginVo.setUsername(userBO.getUsername());
        loginVo.setType(userBO.getType());

        loginVo.setRefreshToken(DoubleToken.getRefreshToken(userBO.getId(), userBO.getType(),0));

        return ResponseEntity.ok().body(new ResponseClass(HttpStatus.OK.value(), loginVo, "登录成功"));
    }


    @GetMapping("/getUserInfo")
    public ResponseEntity<?> getUserInfo(@RequestParam Integer userId){
        return getResponseEntity(userId);
    }


    @GetMapping("/getSelfInfo")
    public ResponseEntity<?> getSelfInfo() {
        Integer userId = UserUtil.getId();
        return getResponseEntity(userId);
    }



    private ResponseEntity<?> getResponseEntity(@RequestParam Integer userId) {
        UserBO userBO = userService.getUserById(userId);
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setId(userBO.getId());
        userInfoVO.setNickname(userBO.getNickname());
        userInfoVO.setUsername(userBO.getUsername());
        userInfoVO.setType(userBO.getType());
        return ResponseEntity.ok().body(new ResponseClass(HttpStatus.OK.value(), userInfoVO, "获取成功"));
    }


    @PostMapping("/register")
    public ResponseEntity<?> register(@RequestBody RegisterDTO registerDTO) {
        // 用户名的正则表达式：只包含英文大小写字母、数字和下划线，长度为6-20个字符
        final String USERNAME_REGEX = "^[a-zA-Z0-9_]{6,20}$";
        // 密码的正则表达式：只包含英文大小写字母、数字和特殊字符，长度为8-20个字符
        final String PASSWORD_REGEX = "^[a-zA-Z0-9!@#$%^&*()-_=+\\\\|\\[\\]{};:'\",.<>/?]{8,20}$";

        if (StrUtil.isBlank(registerDTO.getNickname()) || StrUtil.isBlank(registerDTO.getUsername()) || StrUtil.isBlank(registerDTO.getPassword()) || registerDTO.getType() == null) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseClass(HttpStatus.BAD_REQUEST.value(), null, "信息不能为空"));
        }

        if (registerDTO.getNickname().length()>20) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseClass(HttpStatus.BAD_REQUEST.value(), null, "昵称长度不能超过20个字符"));
        }
        if (registerDTO.getType() == 0) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseClass(HttpStatus.BAD_REQUEST.value(), null, "该用户类型不能注册"));
        }


        if (!registerDTO.getUsername().matches(USERNAME_REGEX)) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseClass(HttpStatus.BAD_REQUEST.value(), null, "用户名应只包含英文大小写字母、数字和下划线，长度为6-20个字符"));
        }
        if (!registerDTO.getPassword().matches(PASSWORD_REGEX)) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseClass(HttpStatus.BAD_REQUEST.value(), null, "密码应只包含英文大小写字母、数字和特殊字符，长度为8-20个字符"));
        }

        if (userService.getUserIdByUserName(registerDTO.getUsername()) != -1) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseClass(HttpStatus.BAD_REQUEST.value(), null, "用户名已存在"));
        }

        Integer userId = userService.addUser(registerDTO);
        if (userId == null || userId == -1) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseClass(HttpStatus.BAD_REQUEST.value(), null, "注册失败"));
        }
        return ResponseEntity.ok().body(new ResponseClass(HttpStatus.OK.value(), null, "注册成功"));
    }

    @GetMapping("/refreshToken")
    public ResponseEntity<?> getAccessToken(@RequestHeader(name = "RefreshToken") String refreshToken) {
        if (!DoubleToken.verifyRefreshToken(refreshToken)) {
            return ResponseEntity.status(419).body(new ResponseClass(419, null, "登录过期，请重新登录"));
        }
        String newRefreshToken = null;
        Integer userId = DoubleToken.getID(refreshToken);
        Integer type = DoubleToken.getType(refreshToken);
        Integer count = DoubleToken.getCount(refreshToken);
        if (DoubleToken.isNeedRefresh(refreshToken)){
            if (count < 5) {
                newRefreshToken = DoubleToken.getRefreshToken(userId, type, count + 1);
            }
        }

        Map<String,String> res = new HashMap<>();
        res.put("accessToken", DoubleToken.getAccessToken(userId, type));
        if (newRefreshToken != null){
            res.put("refreshToken", newRefreshToken);
        }
        return ResponseEntity.ok().body(new ResponseClass(HttpStatus.OK.value(), res, "获取成功"));
    }



    @GetMapping("/userList")
    @RequiresPermission({0})
    public ResponseEntity<?> getUserList() {
        List<UserInfoVO> userInfoVOList = userService.getAllUser().stream()
                .map(userBO -> {
                    UserInfoVO userInfoVO = new UserInfoVO();
                    userInfoVO.setId(userBO.getId());
                    userInfoVO.setNickname(userBO.getNickname());
                    userInfoVO.setUsername(userBO.getUsername());
                    userInfoVO.setType(userBO.getType());
                    return userInfoVO;
                })
                .collect(Collectors.toList());
        return ResponseEntity.ok().body(new ResponseClass(HttpStatus.OK.value(),userInfoVOList, "获取成功"));
    }
}
